package org.yawnage.framework
{
	import org.yawnage.base.BaseKeyMapper;
	import org.yawnage.framework.server.Publisher;
	import flash.utils.Dictionary;
	import org.yawnage.interfaces.framework.IClient;
	
	/**
	 * <p>//TODO:To be written</p>
	 * @author Berry Jordaan
	 * @date 2011/09/06 02:00 PM
	 * @copyright  Copyright © Berry/James 2011
	 * @version 1.0.0.0
	 * @filename Broker.as
	 * @description
	 * @history Berry Jordaan on 2011/09/06 02:00 PM: Created
	 */
	public class ClientMap extends BaseKeyMapper implements IClient
	{
		
		//************** Enums **************
		
		//************** Public *************
		
		//************** Private ************
		
		//************** protected **********
		
		/**
		 * Constructor
		 */
		public function ClientMap()
		{
			super();
			setClassDescription("org.yawnage.framework.ClientMap");
		}
		
		/**
		 * useless comment here!
		 */
		override public function dispose():void
		{
			super.dispose();
		}
		
		/* INTERFACE org.yawnage.base.interfaces.framework.IClient */
		
		public function getBridge(publisherName:String, serviceNamespace:String):Bridge
		{
			if (!hasObject(publisherName))
			{
				addObject(new ClientObject(publisherName));
			}
			var clObj:ClientObject = ClientObject(getObjectbyKey(publisherName));
			
			if (!clObj.hasBridge(serviceNamespace))
			{
				clObj.addBridge(new Bridge(publisherName, serviceNamespace));
			}
			
			return ClientObject(getObjectbyKey(publisherName)).getBridge(serviceNamespace);
		}
		
		public function unSubscribeAllFromService(publisherName:String, serviceName:String):void
		{
			if (!hasObject(publisherName))
			{ //Test for publisher
				throw new Error("ERROR: Unknown Publisher [" + publisherName + "] - " + toString());
			}
			
			if (!ClientObject(getObjectbyKey(publisherName)).hasBridge(serviceName))
			{ //Test for Service
				throw new Error("ERROR: Unknown Service [" + serviceName + "] - " + toString());
			}
			
			ClientObject(getObjectbyKey(publisherName)).getBridge(serviceName).unSubscribeAll();
			ClientObject(getObjectbyKey(publisherName)).getBridge(serviceName).dispose();
			ClientObject(getObjectbyKey(publisherName)).removeBridge(serviceName);
			removeObject(publisherName);
		}
		
		public function unSubscribeAllFromPublisher(publisherName:String):void
		{
			if (!hasObject(publisherName))
			{ //Test for publisher
				throw new Error("ERROR: Unknown Publisher [" + publisherName + "] - " + toString());
			}
			
			var d:Dictionary = ClientObject(getObjectbyKey(publisherName)).getMap();
			for each (var obj:Bridge in d)
			{
				obj.unSubscribeAll();
				removeObject(publisherName);
			}
		}
		
		public function unSubscribeAll():void
		{
			for each (var obj:ClientObject in _mapper)
			{
				unSubscribeAllFromPublisher(obj.key);
				removeObject(obj.key);
			}
		}
		
		public function integrityCheck():Number
		{
			var num:int = 0;
			var L:int = _mapperList.length;
			for (var i:int = 0; i < L; i++)
			{
				var cl:ClientObject = ClientObject(_mapperList[i]);
				var clntL:Dictionary = cl.getMap();
				var publ:Publisher = Broker.instance.publisherByName(cl.key) as Publisher;
				for each (var br:Bridge in clntL)
				{
					var listT:Dictionary = br.returnSubscribers();
					if (br.numberSubscribers > 0)
					{
						if (!Broker.instance.isPublisher(cl.key))
						{
							_trace("The following Subscribers subscribed to a Publisher [" + cl.key + "] that don't exist:", this, 0x008000);
							++num;
							for (var lst:String in listT)
							{
								_trace("      " + listT[lst].subscriber.toString(), this, 0x808000);
							}
						}
						else
						{
							if (publ.registeredServices == 0)
							{
								_trace("The Publisher [" + cl.key + "] has the following subscribers but no Services:  CLASS:" + publ.toString(), this, 0x008000);
								++num;
								for (var lstT:String in listT)
								{
									_trace("      " + listT[lstT].subscriber.toString(), this, 0x808000);
								}
							}
							else
							{
								if (publ.serviceList()[br.service] == null)
								{
									_trace("The following Subscribers subscribes to a Service [" + br.service + "] that don't exist in " + publ.toString(), this, 0x008000);
									++num;
									for (var lstH:String in listT)
									{
										_trace("      " + listT[lstH].subscriber.toString(), this, 0x808000);
									}
								}
								
							}
						}
					}
					else
					{
						++num;
						_trace("Publisher [" + cl.key + "] has a service ["+br.service+"] with no subscribers:  CLASS:" + publ.toString(), this, 0x008000);
					}
				}
			}
			return num;
		}
		
	}
}